<!DOCTYPE html>
<html lang="en">
  <head>
    <title>
        Java-framework-SpringMVC-1 - rulerLwx Blog
      </title>
        <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no,email=no,adress=no">
    
    <meta name="theme-color" content="#000000" />
    
    <meta http-equiv="window-target" content="_top" />
    
    
    <meta name="description" content="概述 SpringMVC通过一套MVC注解，让POJO成为处理请求的控制器，而无须实现任何接口。支持REST风格的URL请求。 MVC，即Mod" />
    <meta name="generator" content="Hugo 0.73.0 with theme pure" />
    <title>Java-framework-SpringMVC-1 - rulerLwx Blog</title>
    
    
    <link rel="stylesheet" href="https://rulerLwx.gitee.io/css/style.min.c4bc7071f132c964c2116bca53b392933f377e5ca7b7051ed245187c621a2d3e.css">
    
    <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css" async>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css" async>
    <meta property="og:title" content="Java-framework-SpringMVC-1" />
<meta property="og:description" content="概述 SpringMVC通过一套MVC注解，让POJO成为处理请求的控制器，而无须实现任何接口。支持REST风格的URL请求。 MVC，即Mod" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://rulerLwx.gitee.io/2020/07/java-framework-springmvc-1/" />
<meta property="article:published_time" content="2020-07-01T18:58:47+08:00" />
<meta property="article:modified_time" content="2020-07-01T18:58:47+08:00" />
<meta itemprop="name" content="Java-framework-SpringMVC-1">
<meta itemprop="description" content="概述 SpringMVC通过一套MVC注解，让POJO成为处理请求的控制器，而无须实现任何接口。支持REST风格的URL请求。 MVC，即Mod">
<meta itemprop="datePublished" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="dateModified" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="wordCount" content="7715">



<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Java-framework-SpringMVC-1"/>
<meta name="twitter:description" content="概述 SpringMVC通过一套MVC注解，让POJO成为处理请求的控制器，而无须实现任何接口。支持REST风格的URL请求。 MVC，即Mod"/>

    <!--[if lte IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
      <![endif]-->

    <!--[if lt IE 9]>
        <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
      <![endif]-->
  </head>

  
  

  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://gitee.com/rulerLwx" target="_blank">
            <img class="img-circle img-rotate" src="https://rulerLwx.gitee.io/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">rulerLwx</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">thinking...</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Guangzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="Type something..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">Home</span>
                </a>
            </li>
            <li class="menu-item menu-item-archives">
                <a href="/posts/">
                    <i class="icon icon-archives-fill"></i>
                  <span class="menu-title">Archives</span>
                </a>
            </li>
            <li class="menu-item menu-item-categories">
                <a href="/categories/">
                    <i class="icon icon-folder"></i>
                  <span class="menu-title">Categories</span>
                </a>
            </li>
            <li class="menu-item menu-item-tags">
                <a href="/tags/">
                    <i class="icon icon-tags"></i>
                  <span class="menu-title">Tags</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/about/">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">About</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>

<aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">enjoy~
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> Categories</h3>
    <div class="widget-body">
        <ul class="category-list">
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-framework/" class="category-list-link">java-framework</a><span class="category-list-count">38</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-front-end/" class="category-list-link">java-front-end</a><span class="category-list-count">11</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-se/" class="category-list-link">java-se</a><span class="category-list-count">21</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-senior/" class="category-list-link">java-senior</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/linux/" class="category-list-link">linux</a><span class="category-list-count">13</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/tools/" class="category-list-link">tools</a><span class="category-list-count">1</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E7%83%A9/" class="category-list-link">技术杂烩</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/" class="category-list-link">数据库</a><span class="category-list-count">15</span></li>
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> Tags</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/jvm/" class="tag-list-link">jvm</a><span
                    class="tag-list-count">1</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="tag-list-link">多线程</a><span
                    class="tag-list-count">2</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/" class="tag-list-link">网络编程</a><span
                    class="tag-list-count">3</span></li>
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E4%B8%80%E6%89%B9%E9%87%8F%E7%A7%BB%E5%8A%A8%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/" class="title">自己动手（一）——批量移动、重命名文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-27 17:50:02 &#43;0800 CST" itemprop="datePublished">2020-07-27</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E5%85%B3%E4%BA%8Einteger%E7%9A%84-128~127%E7%BC%93%E5%AD%98/" class="title">关于Integer的 -128~127缓存</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-11 16:56:21 &#43;0800 CST" itemprop="datePublished">2020-07-11</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" class="title">跨域问题</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-08 22:41:12 &#43;0800 CST" itemprop="datePublished">2020-07-08</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="title">个人博客搭建</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-05 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-05</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/centos/" class="title">CentOS-</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <h4 class="toc-title">Catalogue</h4>
    <nav id="toc" class="js-toc toc">

    </nav>
  </div>
</aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/2020/07/java-framework-springmvc-1/"
    >Java-framework-SpringMVC-1</a
  >
</h1>

      <div class="article-meta">
        
<span class="article-date">
  <i class="icon icon-calendar-check"></i>&nbsp;
<a href="https://rulerLwx.gitee.io/2020/07/java-framework-springmvc-1/" class="article-date">
  <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
</a>
</span>
<span class="article-category">
  <i class="icon icon-folder"></i>&nbsp;
  <a class="article-category-link" href="/categories/java-framework/"> Java-framework </a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i>&nbsp;<a href="/2020/07/java-framework-springmvc-1/#comments"
            class="article-comment-link">Comments</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 7715words</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 16minutes </span>
      </div>
    </div>
    <div class="article-entry marked-body js-toc-content" itemprop="articleBody">
      <h1 id="概述">概述</h1>
<p>SpringMVC通过一套MVC注解，让POJO成为处理请求的控制器，而无须实现任何接口。支持REST风格的URL请求。</p>
<p>MVC，即Model-View-Controller。Model指数据模型，可以是数据查询得到的数据，也可以是第三方接口返回的数据；View指页面，可以是JSP，Html；Controller指使用@Controller标注的类。</p>
<h1 id="hello-world">Hello World</h1>
<p>1、jar包。</p>
<pre><code class="language-xml">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;com.demo&lt;/groupId&gt;
  &lt;artifactId&gt;SpringMVCTest&lt;/artifactId&gt;
  &lt;packaging&gt;war&lt;/packaging&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;SpringMVCTest Maven Webapp&lt;/name&gt;
  &lt;url&gt;http://maven.apache.org&lt;/url&gt;
  &lt;properties&gt;
		&lt;project.build.sourceEncoding&gt;UTF8&lt;/project.build.sourceEncoding&gt;
		&lt;spring.version&gt;4.0.8.RELEASE&lt;/spring.version&gt;
		&lt;slf4j.version&gt;1.6.6&lt;/slf4j.version&gt;
		&lt;log4j.version&gt;1.2.12&lt;/log4j.version&gt;
		&lt;mybatis.version&gt;3.2.4&lt;/mybatis.version&gt;
		&lt;aspectj.version&gt;1.8.10&lt;/aspectj.version&gt;
	&lt;/properties&gt;
	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;junit&lt;/groupId&gt;
			&lt;artifactId&gt;junit&lt;/artifactId&gt;
			&lt;version&gt;4.11&lt;/version&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;javax.servlet&lt;/groupId&gt;
			&lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
			&lt;version&gt;2.5&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;!-- springframe start --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-core&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-aop&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-web&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-oxm&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;!-- springframe end --&gt;
		
		&lt;dependency&gt;
			&lt;groupId&gt;commons-logging&lt;/groupId&gt;
			&lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
			&lt;version&gt;1.1.1&lt;/version&gt;
		&lt;/dependency&gt;

		&lt;!--使用AspectJ方式注解需要相应的包 --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.aspectj&lt;/groupId&gt;
			&lt;artifactId&gt;aspectjrt&lt;/artifactId&gt;
			&lt;version&gt;${aspectj.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;!--使用AspectJ方式注解需要相应的包 --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.aspectj&lt;/groupId&gt;
			&lt;artifactId&gt;aspectjweaver&lt;/artifactId&gt;
			&lt;version&gt;${aspectj.version}&lt;/version&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;
  &lt;build&gt;
    &lt;finalName&gt;SpringMVCTest&lt;/finalName&gt;
  &lt;/build&gt;
&lt;/project&gt;
</code></pre>
<p>2、在web.xml中配置DispatcherServlet。</p>
<pre><code class="language-xml">&lt;!DOCTYPE web-app PUBLIC
 &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;
 &quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot; &gt;

&lt;web-app&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;springMVC3&lt;/servlet-name&gt;
		&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
			&lt;param-value&gt;classpath:config/springmvc.xml&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;springMVC3&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;

</code></pre>
<p>注意<code>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</code>是<code>/</code>而不是<code>/*</code></p>
<p>默认配置文件名称问题：WEB-INF/[servlet的名称]-servlet.xml，[xxx]即为servlet的名称</p>
<p>3、加入SpringMVC配置文件<code>springmvc.xml</code></p>
<p>需要配置两个：</p>
<p>1）<a href="context:component-scan.../">context:component-scan.../</a>自动扫描controller包。<br>
2）视图解析器：InternalResourceViewResolver，定义前缀、后缀。</p>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd&quot;&gt;
		
	&lt;context:component-scan base-package=&quot;com.demo.controller&quot;&gt;&lt;/context:component-scan&gt;
	
	&lt;!-- 定义视图文件解析 --&gt;
    &lt;bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
        &lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot;/&gt;
        &lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot;/&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
<p>4、编写处理器类，并使用@Controller注解标识为处理器。</p>
<pre><code class="language-java">@Controller
@RequestMapping(&quot;/helloworld&quot;)
public class HelloWorldController {

	@RequestMapping(&quot;/hello&quot;)
	public String hello(){
		System.out.println(&quot;hello world&quot;);
		return &quot;sucess&quot;;
	}
}
</code></pre>
<p>5、编写jsp（省略……）</p>
<p>1、2、3、4、5步完成后，启动服务器测试即可。</p>
<p>注意：</p>
<p>1）如果web.xml中配置DispatcherServlet时不指定<code>contextConfigLocation</code>参数，则可使用默认的配置文件。默认的配置的路径和文件命名如下：/WEB-INF/<!-- raw HTML omitted -->-servlet.xml。其中能改变是只是<!-- raw HTML omitted -->。</p>
<p>2）视图解析器中prefix的值最后带“/”，如“/WEB-INF/views/”。</p>
<h1 id="注解">注解</h1>
<h2 id="入参">入参</h2>
<h3 id="requestmapping">@RequestMapping</h3>
<p>@RequestMapping可以指定如下值：</p>
<ul>
<li>
<p>value：请示的URL。</p>
<p>支持Ant风格：</p>
<ul>
<li>？：匹配文件名中的一个字符。</li>
<li>*：匹配文件名中的任意字符（无或多个字符）。</li>
<li>**：匹配多层路径。</li>
</ul>
<p>示例：</p>
<ul>
<li>/user/*/createUser，匹配/user/aaa/createUser、/user/bbb/createUser等路径。</li>
<li>/user/**/createUser，匹配/user/createUser、/user/aaa/bbb/createUser等路径。</li>
<li>/user/createUser??，匹配/user/createUseraa、/user/createUserbb等路径。</li>
</ul>
</li>
<li>
<p>method：请求的方式（RequestMethod.GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.）</p>
</li>
<li>
<p>params：请求的参数。支持简单的表达式：</p>
<ul>
<li>param1：表示请求必须包含名为param1的请求参数。</li>
<li>!param1：表示请求不能包含名为param1的请求参数。</li>
<li>param1 != value1：表示请求包含名为param1，且其值不为value1的参数。</li>
<li>{“param1 = value1”,”param2”}：表示请求包含名为param1、param2的参数，且param1的值必须为value1。</li>
</ul>
</li>
<li>
<p>heads：请求头。表达式同params。如：headers={&ldquo;Accept-Language=zh-CN,zh;q=0.8&rdquo;}</p>
</li>
<li>
<p>consumes：</p>
</li>
<li>
<p>produces：。如：produces = &ldquo;application/json&rdquo;</p>
</li>
</ul>
<h3 id="pathvariable">@PathVariable</h3>
<p>@PathVariable修饰参数。</p>
<p>目的：为了支持REST风格。</p>
<p>作用：将URL中的占位符参数绑定到处理方法的入参中。</p>
<p>示例：</p>
<pre><code class="language-java">@RequestMapping(&quot;delete/{id}&quot;)
public String delete(@PathVariable(&quot;id&quot;)Integer id){
	userDao.delete(id);
	return &quot;redirect:/user/list.action&quot;;
}
</code></pre>
<h3 id="requestparam">@RequestParam</h3>
<p>@RequestParam修饰参数，用于把get方式或post方式（如文件上传时）请求的参数绑定到方法入参中。可以设置如下值：</p>
<ul>
<li>value：前端的参数名称</li>
<li>required：是否是必传。</li>
<li>defaultValue：默认值。</li>
</ul>
<p>示例：</p>
<p>页面写法：<code>&lt;a href=&quot;requestParamTest/testRequestParam?id=1&quot;&gt;测试@RequestParam&lt;/a&gt;</code></p>
<p>后台写法：</p>
<pre><code class="language-java">@RequestMapping(value=&quot;/testRequestParam&quot;)
public String testRequestParam(@RequestParam(&quot;id&quot;) Integer id){
	System.out.println(&quot;testRequestParam,id = &quot;+id);
	return SUCESSED;
}
</code></pre>
<p>这样就把页面提交的id值绑定到名为id的入参中。当然，<strong>名称相同，就不用写@RequestParam了</strong>。</p>
<h3 id="requestheader">@RequestHeader</h3>
<p>@RequestHeader访问请求头信息，用法同@RequestParam。</p>
<p>示例：</p>
<p>页面：<code>&lt;a href=&quot;requestParamTest/testRequestHeader&gt;测试@RequestHeader&lt;/a&gt;</code></p>
<p>后台：</p>
<pre><code class="language-java">@RequestMapping(value=&quot;/testRequestHeader&quot;)
public String testRequestHeader(@RequestHeader(value=&quot;Accept-Language&quot;) String lang){
	System.out.println(&quot;testRequestHeader,Accept-Language = &quot;+lang);
	return SUCESSED;
}
</code></pre>
<h3 id="cookievalue">@CookieValue</h3>
<p>@CookieValue将cookie值绑定到处理方法的入参字段。</p>
<p>其中value指定的是cookie的名称。</p>
<p>如何知道cookie的名称呢？可以打开chrome的开发者工具，查看cookie值的名称。如下的请求头中就能找到cookie的名称：</p>
<pre><code class="language-java">Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:JSESSIONID=26EE22932FF862B5C80D1FF6F94BA188
Host:localhost:8080
Upgrade-Insecure-Requests:1
</code></pre>
<p>示例：</p>
<pre><code class="language-java">@RequestMapping(value=&quot;/testCookieValue&quot;)
public String testCookieValue(@CookieValue(value=&quot;JSESSIONID&quot;,required=false) String cookieValue){
	System.out.println(&quot;testRequestHeader,JSESSIONID = &quot;+cookieValue);
	return SUCESSED;
}
</code></pre>
<h3 id="pojo映射请求参数">POJO映射请求参数</h3>
<p>将请求参数映射到普通类POJO对象中。SpringMVC会将请求参数名与POJO属性名自动匹配，自动为对应的属性赋值。支持级联属性。</p>
<p>页面：</p>
<pre><code class="language-html">&lt;form action=&quot;requestParamTest/testPOJOParam&quot; method=&quot;post&quot;&gt;
	用户名：&lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;&lt;br&gt;
	邮箱：&lt;input type=&quot;text&quot; name=&quot;email&quot;&gt;&lt;br&gt;
	省：&lt;input type=&quot;text&quot; name=&quot;addr.province&quot;&gt;&lt;br&gt;
	市：&lt;input type=&quot;text&quot; name=&quot;addr.city&quot;&gt;
	&lt;input type=&quot;submit&quot; value=&quot;测试 testPOJOParam 请求&quot;&gt;
&lt;/form&gt;
</code></pre>
<p>后台：</p>
<pre><code class="language-java">@RequestMapping(value = &quot;/testPOJOParam&quot;)
public String testPOJOParam(PersonInfo personInfo) {
	System.out.println(&quot;testPOJOParam,personInfo = &quot;+personInfo);
	return SUCESSED;
}
</code></pre>
<p>这种POJO不用注解修饰参数。</p>
<p>并且 PersonInfo 自动放入到了 requestScope 中，key 为首字母小写的的名称 personInfo。——20190523</p>
<h3 id="访问servlet-api">访问Servlet API</h3>
<p>处理方法的入参可以访问原生Servlet API，支持访问如下原生的API：</p>
<ul>
<li>HttpServletRequest</li>
<li>HttpServletResponse</li>
<li>HttpSession</li>
<li>java.security.Principal</li>
<li>Locale</li>
<li>InputStream</li>
<li>OutputStream</li>
<li>Reader：</li>
<li>Writer：向客户端写出信息</li>
</ul>
<pre><code class="language-java">@RequestMapping(value = &quot;/testServletAPI&quot;)
public String testServletAPI(HttpServletRequest req,HttpServletResponse resp,Writer write,Reader read) {
	return SUCESSED;
}
</code></pre>
<h2 id="域">域</h2>
<h3 id="mapmodel">Map/Model</h3>
<p>SpringMVC在调用方法前会创建一个隐含的模型对象作为数据的存储容器，如果方法入参中声明了Map或Model类型参数，SpringMVC会将隐含模型的引用传递给这些入参，我们就可以在方法体内访问模型中的所有数据，也可以向模型中添加新的属性数据。</p>
<p>下面的示例中，入参中声明一个Map参数，SpringMvc会把它当作model传到目标页面，也就是在目标页面可通过EL表达式取出其值。</p>
<p>A页面：<code>&lt;a href=&quot;requestParamTest/testMap&quot;&gt;测试testMap&lt;/a&gt;</code></p>
<p>后台：</p>
<pre><code class="language-java">@RequestMapping(value = &quot;/testMap&quot;)
public String testMap(Map&lt;String,Object&gt; map) {
	map.put(&quot;names&quot;,Arrays.asList(&quot;Tom&quot;,&quot;Tony&quot;,&quot;Wiky&quot;));
	System.out.println(map);
	return SUCESSED;
}
</code></pre>
<p>B页面：<code>通过EL表达式取出值names: ${requestScope.names}</code></p>
<p>注意：</p>
<p>1）如果web.xml中使用2.3及以下dtd，则需在使用el表达式的页面中增加&lt;%@page isELIgnored=&quot;false&rdquo; %&gt;配置，el表达式才会生效。</p>
<p>2）如果web.xml中使用2.4及以上dtd，则默认isELIgnored=&quot;false&rdquo;。</p>
<p>总结：这个Map，我们一般传Map就行，也可以传如下Map的子类或Model子类：</p>
<ul>
<li>Model</li>
<li>ModelMap</li>
<li>BindingAwareModelMap</li>
</ul>
<h3 id="sessionattributes">@SessionAttributes</h3>
<p>如果希望在多个请求之间共用某个模型属性（比如方法入参Map中定义的属性名称）数据，则可以在<strong>控制器类</strong>上标注一个@SessionAttributes，SpringMVC会将模型中对应的属性暂存到HttpSession中。</p>
<p>@SessionAttributes可以指定两个属性值：</p>
<ul>
<li>value：指定Model中的key名称，将会把此Model放入session中</li>
<li>types：指定Model中的key对应的value的类型，将会把此Model放入session中</li>
</ul>
<pre><code class="language-java">@Controller
@SessionAttributes(value={&quot;person1&quot;,&quot;person2&quot;})
@RequestMapping(value = &quot;/requestParamTest&quot;)
public class RequestParamTest {
	public static String SUCESSED = &quot;sucess&quot;;
	
	@RequestMapping(value = &quot;/testSessionAttributes&quot;)
	public String testSessionAttributes(Map&lt;String,Object&gt; map) {
		//使用@SessionAttributes(value={&quot;person1&quot;,&quot;person2&quot;})
		//先将person1、person2的属性放在请求域里，再放到了session中
		//也就是说，请求域、session域中都有
		map.put(&quot;person1&quot;, new PersonInfo());
		map.put(&quot;person2&quot;, new PersonInfo());
		return SUCESSED;
	}
</code></pre>
<p>除了可以放Model中的key外，还可以指定key对应的value的类型。</p>
<pre><code class="language-java">@Controller
@SessionAttributes(types={String.class})
@RequestMapping(value = &quot;/requestParamTest&quot;)
public class RequestParamTest {
	public static String SUCESSED = &quot;sucess&quot;;
	
	@RequestMapping(value = &quot;/testSessionAttributes&quot;)
	public String testSessionAttributes(Map&lt;String,Object&gt; map) {
		//因为value1是String类型，所以将会把此Model
		//先放入requeest域中，再放入到session域中
		//也就是说，请求域、session域中都有
		map.put(&quot;key1&quot;, &quot;value1&quot;);
		return SUCESSED;
	}
}
</code></pre>
<h3 id="modelattribute">@ModelAttribute</h3>
<p>1）在更新或修改数据时使用，因为修改数据前在遵循 先查后改</p>
<p>作用：在当前 Controller 的<strong>任何一次请求</strong>之前，都先执行 @ModelAttribute 修饰的方法</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708120216.png" alt="image"></p>
<p>在 @ModelAttribute 修饰的方法中将属性放到 Model 中后，默认约定，其它 Controller 方法入参的首字母小写后跟 Model 中的key相同则会把值传入 Controller 方法</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708120238.png" alt="image"></p>
<p>如果名称不一致，则通过 @ModelAttribute 注入</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708120251.png" alt="image"></p>
<p>资料参考：https://ke.qq.com/course/308755?taid=2321584442619411</p>
<p>总结：此注解慎用。除非一个控制器只对应一个功能，即：所有请求方法之前都需要执行同一个跟入参相关的操作。</p>
<p>2）单独在入参中使用，可以将参数带到页面</p>
<pre><code>public String saveUser(@Valid @ModelAttribute User user, BindingResult result){

}
</code></pre>
<p>可以将 user 带到页面，jsp中可以用 ${user}取值</p>
<h1 id="rest风格">REST风格</h1>
<p>REST，即 Representational State Transfer，（资源）表现层状态转化。</p>
<ul>
<li>资源（Resources）：网络上的一个实体，或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务，总之就是一个具体的存在。可以用一个URI（统一资源定位符）指向它，每种资源对应一个特定的 URI 。要获取这个资源，访问它的URI就可以，因此 URI 即为每一个资源的独一无二的识别符。</li>
<li>表现层（Representation）：把资源具体呈现出来的形式，叫做它的表现层（Representation）。比如，文本可以用 txt 格式表现，也可以用 HTML 格式、XML 格式、JSON 格式表现，甚至可以采用二进制格式。</li>
<li>状态转化（State Transfer）：每发出一个请求，就代表了客户端和服务器的一次交互过程。HTTP协议，是一个无状态协议，即所有的状态都保存在服务器端。因此，如果客户端想要操作服务器，必须通过某种手段，让服务器端发生“状态转化”（State Transfer）。而这种转化是建立在表现层之上的，所以就是 “表现层状态转化”。具体说，就是 HTTP 协议里面，四个表示操作方式的动词：GET、POST、PUT、DELETE。它们分别对应四种基本操作：
<ul>
<li>GET 用来获取资源</li>
<li>POST 用来新建资源</li>
<li>PUT 用来更新资源</li>
<li>DELETE 用来删除资源</li>
</ul>
</li>
</ul>
<p>示例：</p>
<ul>
<li>/order/1 	HTTP GET ：得到 id = 1 的 order</li>
<li>/order/1 	HTTP DELETE：删除 id = 1的 order</li>
<li>/order/1 	HTTP PUT：更新id = 1的 order</li>
<li>/order 	HTTP POST：新增 order</li>
</ul>
<p>平常我们只使用GET、POST请求（浏览器 form 表单只支持 GET 与 POST 请求，而DELETE、PUT等方法并不支持）</p>
<p>为了支持REST风格，Spring提供了 HiddenHttpMethodFilter <strong>过滤器</strong>，可以将这些请求转换为标准的http方法，使得支持 GET、POST、PUT、DELETE 请求。</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708120311.png" alt="image"></p>
<p>使用REST风格，步骤如下：</p>
<p>1、在web.xml文件中配置HiddenHttpMethodFilter过滤器：</p>
<pre><code class="language-xml">    &lt;!--启用REST风格请求--&gt;
    &lt;filter&gt;
        &lt;filter-name&gt;hiddenHttpMethodFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.springframework.web.filter.HiddenHttpMethodFilter&lt;/filter-class&gt;
    &lt;/filter&gt;
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;hiddenHttpMethodFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;
</code></pre>
<p>注意：<code>&lt;url-pattern&gt;/*&lt;/url-pattern&gt;</code> 是 <code>/*</code> 而不是 <code>/</code></p>
<p>2、页面的form表单中增加隐藏字段</p>
<pre><code class="language-html">&lt;body&gt;
    &lt;form action=&quot;/test/rest/1&quot; method=&quot;post&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;POST-增&quot;&gt;
    &lt;/form&gt;

    &lt;form action=&quot;/test/rest/1&quot; method=&quot;post&quot;&gt;
        &lt;input type=&quot;hidden&quot; name=&quot;_method&quot; value=&quot;DELETE&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;DELETE-删&quot;&gt;
    &lt;/form&gt;

    &lt;form action=&quot;/test/rest/1&quot; method=&quot;post&quot;&gt;
        &lt;input type=&quot;hidden&quot; name=&quot;_method&quot; value=&quot;PUT&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;PUT-改&quot;&gt;
    &lt;/form&gt;

    &lt;form action=&quot;/test/rest/1&quot; method=&quot;get&quot;&gt;
        &lt;input type=&quot;submit&quot; value=&quot;GET-增&quot;&gt;
    &lt;/form&gt;
&lt;/body&gt;
</code></pre>
<p>其中 DELETE/PUT 请求时，页面要满足两个条件（GET/POST请求不用）：</p>
<ul>
<li>有隐藏域，并且名称是 _method</li>
<li>表单提交方式为 post</li>
</ul>
<p>3、在Controller方法里接收请求，配置对应的请求方法（GET、POST、PUT、DELETE），并使用@PathVariable修饰参数。</p>
<pre><code class="language-java">@Controller
@RequestMapping(&quot;/test&quot;)
public class RestTestController {

    /**
     * 跳转到“增、删、改、查”页面
     */
    @GetMapping(&quot;/testRest&quot;)
    public String testRest(){
        return &quot;restfull&quot;;
    }

    @PostMapping(&quot;/rest/{id}&quot;)
    public String testPost(@PathVariable(&quot;id&quot;)String id) {
        System.out.println(&quot;rest---POST--&quot;+id);
        return &quot;restfull&quot;;
    }

    @DeleteMapping(&quot;/rest/{id}&quot;)
    public String testDelete(@PathVariable(&quot;id&quot;)String id) {
        System.out.println(&quot;rest---Delete--&quot;+id);
        return &quot;restfull&quot;;
    }

    @PutMapping(&quot;/rest/{id}&quot;)
    public String testPUT(@PathVariable(&quot;id&quot;)String id) {
        System.out.println(&quot;rest---PUT--&quot;+id);
        return &quot;restfull&quot;;
    }

    @GetMapping(&quot;/rest/{id}&quot;)
    public String testGET(@PathVariable(&quot;id&quot;)String id) {
        System.out.println(&quot;rest---GET--&quot;+id);
        return &quot;restfull&quot;;
    }

}
</code></pre>
<p>注意：<code>@xxxMapping(&quot;/rest/{id}&quot;)</code> 中的取值用 <code>{}</code> 而不是 <code>${}</code></p>
<p><strong>总结</strong>：</p>
<p>为什么要用<code>_method</code>呢？因为HiddenHttpMethodFilter中会根据_method来包装方法。</p>
<p>疑问：但为什么要这样包装？</p>
<p>答：因为浏览器只支持 get/post 方式，为了支持 DELETE/PUT 请求，所以增加了过滤器。</p>
<hr>
<p>什么是“幂等”？<del>大白话：在操作成功的前提下，会不会对数据库造成不好的影响。不会，则幂等；会，则不幂等。</del></p>
<p><del>参考</del>：https://www.bilibili.com/video/BV1vE411v7h7?p=5</p>
<p>什么是“幂等”？用通俗的话讲：就是针对一个操作，不管做多少次，产生效果或返回的结果都是一样的</p>
<p>参考：</p>
<ul>
<li><a href="https://www.jianshu.com/p/cea3675a590b">https://www.jianshu.com/p/cea3675a590b</a></li>
<li><a href="https://blog.csdn.net/garfielder007/article/details/55684420">https://blog.csdn.net/garfielder007/article/details/55684420</a></li>
</ul>
<h1 id="视图解析">视图解析</h1>
<h2 id="基本流程">基本流程</h2>
<p>Controller中的方法可以返回String、View、ModelAndView，Spring最终都终都会转为ModelAndView，然后通过ViewResolver进行解析。</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708120339.png" alt="image"></p>
<p>下面是常用视图解析器：</p>
<table>
<thead>
<tr>
<th>大类</th>
<th>视图类型</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>解析为Bean的名字</td>
<td>BeanNameViewResolver</td>
<td>将逻辑视图名解析为一个Bean，Bean的id等于逻辑视图名</td>
</tr>
<tr>
<td>解析为URL文件</td>
<td>InternalResourceViewResolver <!-- raw HTML omitted -->  JasperReportsViewResolver</td>
<td></td>
</tr>
<tr>
<td>模板文件视图</td>
<td>FreeMarkerViewResolver <!-- raw HTML omitted -->  VelocityLayoutViewResolver <!-- raw HTML omitted --> VelocityViewResolver</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="mvcview-controller"><a href="mvc:view-controller.../">mvc:view-controller.../</a></h2>
<p>如果想要直接访问页面而不需要经过Controller处理，则可在springmvc的配置文件中增加如下标签配置：</p>
<ul>
<li>
<p>&lt;mvc:view-controller path=&rdquo;/sucess&rdquo; view-name=&quot;sucess&rdquo;/&gt;</p>
<ul>
<li>path表示访问的路径，如http://localhost:8080/myProject/sucess，就会直接跳转到sucess视图。</li>
<li>view-name表示视图名称，此视图也需要经SpringMVC解析后的视图，比如要加上前缀与后缀等。</li>
</ul>
</li>
<li>
<p><a href="mvc:annotation-driven/">mvc:annotation-driven/</a></p>
<p>此配置一般都要配置上。如果配置了<a href="mvc:view-controller.../">mvc:view-controller.../</a>，而不配置<a href="mvc:annotation-driven/">mvc:annotation-driven/</a>，则程序会报错。具体原因，TOD&hellip;.</p>
</li>
</ul>
<h2 id="自定义视图">自定义视图</h2>
<p>1、实现View接口来定义自己的视图，并用<code>@Component</code>标识此类，让SpringMVC可以扫描到自定义的视图。</p>
<pre><code class="language-java">@Component
public class HelloView implements View{
	@Override
	public String getContentType() {
		return &quot;text/html&quot;;
	}
	@Override
	public void render(Map&lt;String, ?&gt; model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		response.getWriter().write(&quot;hello view ,time:&quot;+new Date());
	}
}
</code></pre>
<p>上面定义了一个id为“helloView”的视图。</p>
<p>2、在springmvc配置文件中配置BeanNameViewResolver解析器，此解析器是根据IOC容器中的bean的id来获取视图解析器。</p>
<pre><code class="language-xml">&lt;bean class=&quot;org.springframework.web.servlet.view.BeanNameViewResolver&quot; &gt;
	&lt;property name=&quot;order&quot; value=&quot;100&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<p>注：视图解析器的先后顺序用order属性表示，值越小，优先级越高。</p>
<p>InternalResourceViewResolver的order = Integer.MAX_VALUE，所以它会最后执行。</p>
<p>3、在Controller方法中的返回刚刚自定义的视图名字。视图名，默认是类名第一个字母小写后的名字。</p>
<pre><code class="language-java">@RequestMapping(&quot;/testView&quot;)
public String testView(){
	System.out.println(&quot;testView&quot;);
	return &quot;helloView&quot;;
}
</code></pre>
<p>此处返回的就是前面自定义的“helloView”视图。</p>
<p>4、页面测试：<code>&lt;a href=&quot;requestParamTest/testView&quot;&gt;测试自定义视图testView&lt;/a&gt;</code></p>
<h2 id="转发与重定向">转发与重定向</h2>
<p>转发：</p>
<p>重定向：一个web资源收到客户端请求后，通知客户端去访问另一个web资源。特点：地址栏发生变化。</p>
<p>Controller中，如果返回的字符串中带有<code>forward:</code>或<code>redirect:</code>前缀时，SpringMVC会对他们进行转发或重定向操作：</p>
<ul>
<li>forward:/sucess.jsp，会完成一个到sucess.jsp（项目根目录下的）的转发操作</li>
<li>redirect:/sucess.jsp，会完成一个到sucess.jsp（项目根目录下的）的重定向操作</li>
</ul>
<h2 id="el表达式">EL表达式</h2>
<p>1、加入Jar包</p>
<pre><code class="language-xml">&lt;dependency&gt;
	&lt;groupId&gt;jstl&lt;/groupId&gt;
	&lt;artifactId&gt;jstl&lt;/artifactId&gt;
	&lt;version&gt;1.2&lt;/version&gt;
&lt;/dependency&gt;
&lt;!--jstl 1.2 不需要 standard 包--&gt;
&lt;dependency&gt;
	&lt;groupId&gt;taglibs&lt;/groupId&gt;
	&lt;artifactId&gt;standard&lt;/artifactId&gt;
	&lt;version&gt;1.1.2&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<p>2、jsp页面引入 c标签</p>
<p><code>&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt; </code></p>
<p>在jsp中拿到绝对路径：</p>
<pre><code class="language-html">&lt;form action=&quot;${pageContext.request.contextPath }/emp&quot;&gt;
&lt;/form&gt;
</code></pre>
<p>在开发中推荐使用绝对路径。</p>
<h2 id="处理静态资源">处理静态资源</h2>
<p>由于web.xml文件中配置的SpringMVC的拦截器拦截所有的资源（“/”），包括静态资源等，因找不到静态资源对应的处理器，所以会报错。可以通过在springMVC的配置文件中增加如下标签配置：</p>
<p><a href="mvc:default-servlet-handler/">mvc:default-servlet-handler/</a></p>
<p>此标签表示：将在SpringMVC上下文中定义一个DefaultServletHttpRequestHandler，它会对进入DispatchServlet的请求进行筛查，如果发现是没有经过映射的请求，就将请求交由WEB应用服务器默认的Servlet处理，如果不是静态资源的请求，才由DispatchServlet继续处理。</p>
<p>一般WEB应用服务器默认的Servlet的名称都是default。若所使用的WEB服务器默认的Servlet名称不是default，则需要通过default-servlet-name属性来显式指定默认的服务器名。</p>
<ul>
<li>比如：apache-tomcat-7.0.42\conf\web.xml中就配置有一个名为default的servlet。</li>
<li>通过default-servlet-name属性来显式指定：&lt;mvc:default-servlet-handler default-servlet-name=&quot;xxxx&rdquo;/&gt;</li>
</ul>
<p>注意：配置<a href="mvc:default-servlet-handler/">mvc:default-servlet-handler/</a>时，也要配置<a href="mvc:annotation-driven/">mvc:annotation-driven/</a>。否则报错。</p>
<h2 id="国际化i18n">国际化（i18n）</h2>
<p>参考自己的代码 <a href="https://github.com/wolf-lea/spring-mvc-demo/tree/master/spring-mvc-i18n">https://github.com/wolf-lea/spring-mvc-demo/tree/master/spring-mvc-i18n</a></p>
<h3 id="步骤一写properties文件">步骤一：写properties文件</h3>
<p>在resources下新建 i18n 文件夹，创建以下3个文件：</p>
<p>base.properties</p>
<pre><code class="language-properties">resource.welcome=WELCOME
resource.exit=EXIST
</code></pre>
<p>base_en_US.properties</p>
<pre><code class="language-properties">resource.welcome=welcome
resource.exit=exist
</code></pre>
<p>i18n_zh_CN.properties</p>
<pre><code class="language-properties">    resource.welcome=欢迎
    resource.exit=退出
</code></pre>
<p>国际化文件命名规则，参考：https://wangxingguang.iteye.com/blog/1861160</p>
<h3 id="步骤二配置-resourcebundlemessagesource">步骤二：配置 ResourceBundleMessageSource</h3>
<p>在springmvc配置文件（比如springmvc-servlet.xml）中配置 ResourceBundleMessageSource，用于绑定properties文件</p>
<pre><code class="language-xml">    &lt;!--加载国际化文件--&gt;
    &lt;bean id=&quot;messageSource&quot; class=&quot;org.springframework.context.support.ResourceBundleMessageSource&quot;&gt;
        &lt;property name=&quot;basename&quot; value=&quot;i18n.base&quot;/&gt;
        &lt;property name=&quot;defaultEncoding&quot; value=&quot;UTF-8&quot;/&gt;
    &lt;/bean&gt;
</code></pre>
<h3 id="步骤三写controller">步骤三：写controller</h3>
<pre><code class="language-java">@Controller
@RequestMapping(&quot;/test&quot;)
public class I18NController {

    @RequestMapping(&quot;/i18n&quot;)
    public String testI18n(){
        return &quot;i18n&quot;;
    }
}
</code></pre>
<h3 id="步骤四使用jstl标签实现国际化">步骤四：使用JSTL标签实现国际化</h3>
<p>1）加入两个依赖：</p>
<pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;jstl&lt;/groupId&gt;
  &lt;artifactId&gt;jstl&lt;/artifactId&gt;
  &lt;version&gt;1.2&lt;/version&gt;
&lt;/dependency&gt;

&lt;!--jstl 1.2 不再需要standard --&gt;
&lt;!--&lt;dependency&gt;--&gt;
    &lt;!--&lt;groupId&gt;taglibs&lt;/groupId&gt;--&gt;
    &lt;!--&lt;artifactId&gt;standard&lt;/artifactId&gt;--&gt;
    &lt;!--&lt;version&gt;1.1.2&lt;/version&gt;--&gt;
&lt;!--&lt;/dependency&gt;--&gt;
</code></pre>
<p>2）jsp文件引入jstl，并使用其标签实现国际化</p>
<pre><code class="language-jsp">&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; prefix=&quot;fmt&quot;%&gt;

...
    &lt;fmt:message key=&quot;resource.welcome&quot;/&gt;
    &lt;fmt:message key=&quot;resource.exit&quot;/&gt;
...

</code></pre>
<p>测试：访问controller方法，而不是直接访问页面：http://localhost:8080/test/i18n</p>
<h3 id="总结">总结</h3>
<ol>
<li>jstl 1.2 不再需要 standard 包</li>
<li>页面引入的是<code>http://java.sun.com/jsp/jstl/fmt</code>，而不是<code>&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;</code></li>
<li>properties的编码要是 UTF-8
<img src="https://gitee.com/rulerLwx/PicGo/raw/master/img-07/20200708115559.png" alt="image"></li>
<li>ResourceBundleMessageSource 指定编码，否则中文乱码；id=&quot;messageSource&rdquo;，id名称不能变。</li>
</ol>
<pre><code> &lt;property name=&quot;defaultEncoding&quot; value=&quot;UTF-8&quot;/&gt; 
</code></pre>

    </div>
    <div class="article-footer">
<blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    <li class="post-copyright-link hidden-xs">
      <strong>Permalink: </strong>
      <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springmvc-1/" title="Java-framework-SpringMVC-1" target="_blank" rel="external">https://rulerLwx.gitee.io/2020/07/java-framework-springmvc-1/</a>
    </li>
    <li class="post-copyright-license">
      <strong>License：</strong><a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN</a>
    </li>
  </ul>
</blockquote>

<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://gitee.com/rulerLwx" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="https://rulerLwx.gitee.io/avatar.png" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://gitee.com/rulerLwx" target="_blank"><span class="text-dark">rulerLwx</span><small class="ml-1x">thinking...</small></a></h3>
        <div>Good Good Study, Day Day Up~</div>
      </div>
    </figure>
  </div>
</div>
    </div>
  </article>
<section id="comments">
    <div id="vcomments"></div>
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springmvc-2/" title="Java-framework-SpringMVC-2"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;Older</span></a>
            </li>
            <li class="next">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-springcloud-5/"
                    title="Java-framework-SpringCloud-5"><span>Newer&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="Catalogue" role="button">
                    <span>[&nbsp;</span><span>Catalogue</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>

</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://gitee.com/rulerLwx" target="_blank" title="gitee" data-toggle=tooltip data-placement=top >
            <i class="icon icon-gitee"></i></a></li>
    <li><a href="https://github.com/wolf-lea" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2020  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_SVG"></script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
            showMathMenu: false, //disables context menu
            tex2jax: {
            inlineMath: [ ['$','$'], ['\\(','\\)'] ]
           }
    });
</script>


<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script>
    window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/python.min.js" defer></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/javascript.min.js" defer></script><script>
    hljs.configure({
        tabReplace: '    ', 
        classPrefix: ''     
        
    })
    hljs.initHighlightingOnLoad();
</script>
<script src="https://rulerLwx.gitee.io/js/application.min.bdeb64b910570b6c41badc6a05b7afb0c8ad9efd8525de3c7257d59e786326a3.js"></script>
<script src="https://rulerLwx.gitee.io/js/plugin.min.51ff8c7317566f82259170fa36e09c4493adc9b9378b427a01ad3f017ebac7dd.js"></script>

<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            ROOT_URL: 'https:\/\/rulerLwx.gitee.io',
            CONTENT_URL: 'https:\/\/rulerLwx.gitee.io\/searchindex.json ',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script type="text/javascript" src="https://rulerLwx.gitee.io/js/insight.min.a343cd9a5a7698336b28ef3a7c16a3a1b1d2d5fb17dc8ed04022bbe08cc5459073a15bdafa3a8a58cdd56080784bdd69fa70b1ae8597565c799c57ed00f0e120.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script>
<script>
    tocbot.init({
        
        tocSelector: '.js-toc',
        
        contentSelector: '.js-toc-content',
        
        headingSelector: 'h1, h2, h3',
        
        hasInnerContainers: true,
    });
</script>

<script src="https://cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine"></script>
<script type="text/javascript">
    var GUEST = ['nick', 'mail', 'link'];
    var meta = 'nick,mail';
    meta = meta.split(',').filter(function (item) {
        return GUEST.indexOf(item) > -1;
    });
    new Valine({
        el: '#vcomments',
        verify: null ,
        notify: null ,
        appId: 'IyAB0PSPRazTPDxitO1ddQ7O-gzGzoHsz',
        appKey: '5rBJTq4KidYF33eXwvRVhtEH',
        placeholder: 'enjoy~',
        avatar: 'mm',
        meta: meta,
        pageSize: '10' || 10,
        visitor: false 
});
</script>

  </body>
</html>
